from flask import request, g, jsonify, current_app, render_template
from info import db, constants
from info.models import News, Comment
from info.modules.news import news_bp
from info.response_code import RET
from info.utils.common import get_user_info


#---->我的版本v19.01.24<-------
###################################################################
# 新闻详情接口
@news_bp.route("/<int:news_id>")
@get_user_info
def news_detail(news_id):

    print("接口测试............................新闻详情接口")

    """新闻详情接口"""
    # --------------------------1.查询当前用户登陆的信息展示-------------------------
    user = g.user

    # 3.将用户对象转换成字典
    # if user:
    #     user_dict = user.to_dict()
    #
    # 简写法
    user_dict = user.to_dict() if user else None

    # --------------------------2.查询新闻点击排行数据-------------------------
    # news_rank_list = [news_obj1,news_obj2,...]
    try:
        news_rank_list = News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="查询点击排行新闻对象异常")

    # 将新闻对象列表数据转换为字典列表数据
    """
    if news_rank_list:
    for news in news_rank_list:
        news_dict = news.to_dict()
        newsrank_dict_list.append(news_dict)
    """
    newsrank_dict_list = []
    for news in news_rank_list if news_rank_list else []:
        # 将新闻对象转换成字典装入列表中
        newsrank_dict_list.append(news.to_dict())

    # --------------------------3.查询新闻详情数据-------------------------
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAERR,errmsg="查询新闻对象异常")

    # 新闻详情对象转换为字典
    news_detail_dict = news.to_dict() if news else None

    # --------------------4.查询当前用户是否收藏当前新闻-------------------------
    # 定义一个标志位 默认是false:当前用户未收藏该新闻,反之
    is_collected = False

    # 当前用户已经登陆才能去进行查询数据
    if user:
        # 当前新闻在在用户收藏列表中:表示收藏过该新闻
        if news in user.collection_news:
            is_collected = True

    # ------------------5.查询当前新闻对应的评论列表数据-------------------------
    # 查询条件:评论的新闻id == 当前新闻的id,代表的是当前新闻下面的所有评论数据
    try:
        comment_list = Comment.query.filter(Comment.news_id == news_id).order_by(Comment.create_time.desc()).all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAERR,errmsg="查询新闻对象异常")

    # 评论对象列表转字典列表
    comment_dict_list = []
    for comment in comment_list if comment_list else []:
        # 对象转字典
        comment_dict = comment.to_dict()
        comment_dict_list.append(comment_dict)

    # 4.组值返回数据
    """
    数据格式:
        data = {
            "user_info": resp_dict = {
                "id": self.id,
                "nick_name":self.nick_name,
            }
        }
    使用: data.user_info.nick_name
    """
    print("******************************")
    data = {
        "user_info": user_dict,
        "click_news_list":newsrank_dict_list,
        "news":news_detail_dict,
        "is_collected":is_collected,
        "comment_list":comment_dict_list
    }

    return  render_template("news/detail.html",data=data)


#################################################
# 收藏/取消收藏的后端接口
# 127.0.0.1:5000/news/news_collect   参数通过请求体携带
@news_bp.route("/news_collect", methods=["POST"])
@get_user_info
def news_collect():
    print("接口测试............................收藏/取消收藏的后端接口")
    """收藏/取消收藏的后端接口"""
    """
    1.获取参数
        1.1 news_id ;当前新闻id值,action:收藏/取消收藏的行为, user:当前登录的用户
    2.校验参数
        2.1 非空判断
        2.2 action in ["collect","cancel_collect"]
    3.逻辑处理
        3.1 根据新闻id查询新闻对象
        3.2 根据action 判断是收藏还是取消收藏的行为
        收藏:将新闻对象news添加到user.collection_news列表中
        取消收藏:将新闻对象news从user.collection_news列表中清除

        3.3 将上述修改操作保存回数据库
    4.返回值
    """

    # 1.1 news_id:当前新闻id值,action:收藏/取消收藏的行为,user:当前登陆的用户
    news_id = request.json.get("news_id")
    action = request.json.get("action")
    user = g.user

    # 2.1 非空判断
    if not all([news_id, action]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不足")

    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登陆")

    # 2.2 action in ["collect","cancel_collect"]:
    if action not in ["collect", "cancel_collect"]:
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    # 3.1 根据新闻id查询新闻对象
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询新闻对象异常")

    if not news:
        # 新闻对象不存在,不允许收藏
        return jsonify(errno=RET.NODATA, errmsg="新闻对象不存在")

    # 3.2 根据action判断收藏还是取消收藏行为
    if action == "collect":

        # 收藏:将新闻对象news添加到user.collection_news列表当中
        # 当前新闻列表不在当前用户列表中,我们才添加收藏
        if news not in user.collection_news:
            user.collection_news.append(news)

    else:
        # 取消收藏:将新闻对象news从user.collection_news列表中移除
        print("收藏取消测试:.....................取消收藏.....取消收藏....取消收藏.....取消收藏....")
        # 只有新闻在用户的收藏列表中,我们才有资格移除新闻对象,表示取消收藏
        if news in user.collection_news:
            user.collection_news.remove(news)

    # 3.3 将上述修改操作保存回数据库
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        # 数据回滚
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="保存新闻收藏异常")

    return jsonify(errno=RET.OK, errmsg="OK")


######################################################################
# 发布子/主评论后端接口
# 127.0.0.1:5000/news/news_comment  参数通过请求体携带
@news_bp.route("/news_comment",methods=["POST"])
@get_user_info
def news_comment():
    print("0000000000000000000000000000000000000000000000000000000000")
    """发布子/主评论后端接口"""
    """
    1.获取参数
        1.1 news_id 新闻id ,user:当前用户 , comment:评论的内容,parent_id:区分子评论和主评论
    2.校验参数
        2.1 非空判断
    3.逻辑处理
        3.1 根据news_id 获取新闻对象,新闻对象存在才能发布评论
        3.2 创建评论对象
        3.3 parent_id 没有值,创建主评论
        3.4 parent_id 有值,创建子评论
        3.5 将评论对象保存到数据库
    4.返回值
        4.1 发布评论成功
    """

    # 1.1 news_id:新闻id, user:当前登陆的用户 , comment:评论的内容, parent_id:区分主评论和子评论
    news_id = request.json.get("news_id")
    content = request.json.get("comment")
    parent_id = request.json.get("parent_id")
    user = g.user

    # 2.1 非空判断
    if not all([news_id,content]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数不足")
    # 用户未登陆
    if not user:
        return jsonify(errno=RET.SESSIONERR,errmsg="用户未登陆")

    # 3.1 根据news_id获取新闻对象,新闻对象存在才能发布评论
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAERR,errmsg="查询新闻对象异常")
    if not news:
        return jsonify(errno=RET.NODATA,errmsg="新闻不存在,不能发布评论")

    # 3.2 创建评论对象
    comment = Comment()
    # 给各个属性赋值
    comment.user_id = user.id
    comment.news_id = news.id
    comment.content = content

    # 3.3 parent_id 没有值:创建主评论对象
    # 3.4 parent_id 有值:创建子评论对象
    if parent_id:
        comment.parent_id = parent_id

    # 3.5 将评论对象保存回数据库
    try:
        db.session.add(comment)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        # 数据回滚
        db.session.rollback()
        return jsonify(errno=RET.DBERR,errmsg="保存评论对象异常")

    # 考虑到前端发布完评论后,页面需要局部刷新数据,所以需要将评论数据返回
    comment_dict = comment.to_dict() if comment else None
    data = {
        "comment": comment_dict
    }
    return jsonify(errno=RET.OK,errmsg="发布评论成功", data=data)




























# -------------------老陈的版本--------------------------
# from info import constants, db
# from info.models import User, News, Comment
# from info.response_code import RET
# from info.utils.common import get_user_info
# from . import news_bp
# from flask import render_template, session, current_app, jsonify, g, request
#
#
# # 127.0.0.1:5000/news/news_comment  参数通过请求体携带
# @news_bp.route('/news_comment', methods=['POST'])
# @get_user_info
# def news_comment():
#     """发布主/子评论后端接口"""
#     """
#     1.获取参数
#         1.1 news_id:新闻id，user:当前登录的用户，comment:评论的内容，parent_id:区分主评论和子评论字段【非必传】
#     2.参数校验
#         2.1 非空判断
#     3.逻辑处理
#         3.1 根据news_id获取新闻对象，新闻对象存在才能发布评论
#         3.2 创建评论对象
#         3.3 parent_id没有值： 创建主评论对象
#         3.4 parent_id有值：创建子评论对象
#         3.5 将评论对象保存回数据库
#     4.返回值
#         4.1 发布评论成功
#     """
#     # 1.1 news_id:新闻id，user:当前登录的用户，comment:评论的内容，parent_id:区分主评论和子评论字段【非必传】
#     news_id = request.json.get("news_id")
#     content = request.json.get("comment")
#     parent_id = request.json.get("parent_id")
#     user = g.user
#
#     # 2.1 非空判断
#     if not all([news_id, content]):
#         return jsonify(errno=RET.PARAMERR, errmsg="参数不足")
#     # 用户未登录
#     if not user:
#         return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")
#
#     # 3.1 根据news_id获取新闻对象，新闻对象存在才能发布评论
#     try:
#         news = News.query.get(news_id)
#     except Exception as e:
#         current_app.logger.error(e)
#         return jsonify(errno=RET.DBERR, errmsg="查询新闻对象异常")
#     if not news:
#         return jsonify(errno=RET.NODATA, errmsg="新闻不存在不能发布评论")
#
#     # 3.2 创建评论对象
#     comment = Comment()
#     # 给各个属性赋值
#     comment.user_id = user.id
#     comment.news_id = news.id
#     comment.content = content
#     # 3.3 parent_id没有值： 创建主评论对象
#     # 3.4 parent_id有值：创建子评论对象
#     if parent_id:
#         comment.parent_id = parent_id
#
#     # 3.5 将评论对象保存回数据库
#     try:
#         db.session.add(comment)
#         db.session.commit()
#     except Exception as e:
#         current_app.logger.error(e)
#         # 数据回滚
#         db.session.rollback()
#         return jsonify(errno=RET.DBERR, errmsg="保存评论对象异常")
#
#     # 考虑到前端发布完评论后，页面需要局部刷新数据，所以需要将评论数据返回
#     comment_dic = comment.to_dict() if comment else None
#     data = {
#         "comment": comment_dic
#     }
#     return jsonify(errno=RET.OK, errmsg="发布评论成功", data=data)
#
#
# # 127.0.0.1:5000/news/news_collect  参数通过请求体携带
# @news_bp.route('/news_collect', methods=['POST'])
# @get_user_info
# def news_collect():
#     """收藏&取消收藏的后端接口"""
#     """
#     1.获取参数
#         1.1 news_id: 当前新闻id值， action:收藏&取消收藏的行为， user:当前登录的用户
#     2.校验参数
#         2.1 非空判断
#         2.2 action in ["collect", "cancel_collect"]
#     3.逻辑处理
#         3.1 根据新闻id查询新闻对象
#
#         3.2 根据action判断是收藏还是取消收藏的行为
#         收藏：将新闻对象news添加到user.collection_news列表中
#         取消收藏：将新闻对象news从user.collection_news列表中移除
#
#         3.3 将上述修改操作保存回数据库
#     4.返回值
#     """
#
#     # 1.1 news_id: 当前新闻id值， action:收藏&取消收藏的行为， user:当前登录的用户
#     news_id = request.json.get("news_id")
#     action = request.json.get("action")
#     user = g.user
#
#     # 2.1 非空判断
#     if not all([news_id, action]):
#         return jsonify(errno=RET.PARAMERR, errmsg="参数不足")
#
#     if not user:
#         # 用户未登录
#         return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")
#
#     # 2.2 action in ["collect", "cancel_collect"]
#     if action not in ["collect", "cancel_collect"]:
#         return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
#
#     # 3.1 根据新闻id查询新闻对象
#     try:
#         news = News.query.get(news_id)
#     except Exception as e:
#         current_app.logger.error(e)
#         return jsonify(errno=RET.DBERR, errmsg="查询新闻对象异常")
#     if not news:
#         # 新闻对象不存在，不允许收藏
#         return jsonify(errno=RET.NODATA, errmsg="新闻对象不存在")
#
#     # 3.2 根据action判断是收藏还是取消收藏的行为
#     if action == "collect":
#         # 收藏：将新闻对象news添加到user.collection_news列表中
#         # 当前新闻不在当前用户的收藏列表中，我们才添加收藏
#         if news not in user.collection_news:
#             user.collection_news.append(news)
#     else:
#         # 取消收藏：将新闻对象news从user.collection_news列表中移除
#
#         # 只有新闻在用户的收藏列表中，我们才有资格移除新闻对象，表示取消收藏
#         if news in user.collection_news:
#             user.collection_news.remove(news)
#
#     # 3.3 将上述修改操作保存回数据库
#     try:
#         db.session.commit()
#     except Exception as e:
#         current_app.logger.error(e)
#         # 数据回滚
#         db.session.rollback()
#         return jsonify(errno=RET.DBERR, errmsg="保存新闻收藏数据异常")
#
#     return jsonify(errno=RET.OK, errmsg="OK")
#
#
# # 127.0.0.1:5000/news/新闻id
# @news_bp.route('/<int:news_id>')
# @get_user_info
# def news_detail(news_id):
#     """新闻详情接口"""
#     # -----------------------1.查询当前登录用户的信息展示-----------------------------
#     user = g.user
#
#     # 3.将用户对象转换成字典
#     # if user:
#     #     user_dict = user.to_dict()
#     user_dict = user.to_dict() if user else None
#
#     # -----------------------2.查询新闻的点击排行数据-----------------------------
#     # news_rank_list = [news_obj1, news_obj2, ....]
#     try:
#         # 1.新闻点击量降序排序
#         # 2.限制新闻条数为6条
#         news_rank_list = News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
#     except Exception as e:
#         current_app.logger.error(e)
#         return jsonify(errno=RET.DBERR, errmsg="查询点击排行新闻对象异常")
#
#     # 将新闻对象列表数据转换成字典列表数据
#     """
#         if news_rank_list:
#         for news in news_rank_list:
#             news_dict = news.to_dict()
#             newsrank_dict_list.append(news_dict)
#     """
#     newsrank_dict_list = []
#     for news in news_rank_list if news_rank_list else []:
#         # 将新闻对象转换成字典装入列表中
#         newsrank_dict_list.append(news.to_dict())
#
#     # -----------------------3.查询新闻详情数据-----------------------------
#     try:
#         news = News.query.get(news_id)
#     except Exception as e:
#         current_app.logger.error(e)
#         return jsonify(errno=RET.DBERR, errmsg="查询新闻详情对象异常")
#
#     # 新闻详情对象转换成字典
#     news_detail_dict = news.to_dict() if news else None
#
#     # -----------------------4.查询当前用户是否收藏当前新闻-----------------------------
#     # 定义一个标志位 默认值False：当前用户未收藏该新闻，反之
#     is_collected = False
#
#     # 当前用户已经登录才去进行查询数据
#     if user:
#         # 当前新闻在用户的新闻收藏列表中：表示收藏过该新闻
#         if news in user.collection_news:
#             is_collected = True
#     # -----------------------5.查询当前新闻对应的评论列表数据-----------------------------
#     # 查询条件：评论的新闻id == 当前新闻的id，代表查询的是当前新闻下面的所有评论数据
#     try:
#         comment_list = Comment.query.filter(Comment.news_id == news_id).order_by(Comment.create_time.desc()).all()
#     except Exception as e:
#         current_app.logger.error(e)
#         return jsonify(errno=RET.DBERR, errmsg="查询评论数据异常")
#
#     # 评论对象列表转字典列表
#     comment_dict_list = []
#     for comment in comment_list if comment_list else []:
#         # 对象转字典
#         comment_dict = comment.to_dict()
#         comment_dict_list.append(comment_dict)
#
#     # 4.组织返回数据
#     """
#     数据格式：
#         data = {
#             "user_info" : resp_dict = {
#                 "id": self.id,
#                 "nick_name": self.nick_name,
#             }
#         }
#
#     使用： data.user_info.nick_name
#     """
#     data = {
#         "user_info": user_dict,
#         "click_news_list": newsrank_dict_list,
#         "news": news_detail_dict,
#         "is_collected": is_collected,
#         "comment_list": comment_dict_list
#     }
#
#     return render_template("news/detail.html", data=data)



